package com.am.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.am.user.domain.Result;
import com.am.user.domain.dto.LoginFormDTO;
import com.am.user.domain.po.User;
import com.am.user.domain.vo.UserLoginVO;
import com.am.user.mapper.UserMapper;
import com.am.user.properties.JwtProperties;
import com.am.user.service.IUserService;
import com.am.user.utils.JwtUtil;
import com.am.user.utils.SMSUtil;
import com.am.user.utils.ValidateCodeUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.am.user.constant.RedisConstants.LOGIN_CODE_KEY;
import static com.am.user.constant.RedisConstants.LOGIN_CODE_TTL;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService{
    private final StringRedisTemplate stringRedisTemplate;
    private final SMSUtil smsUtil;
    private final JwtProperties jwtProperties;

    @Override
    public Result<UserLoginVO> login(LoginFormDTO loginFormDTO) {
        String phone = loginFormDTO.getPhone();
        String code = loginFormDTO.getCode();
        // 核验验证码
        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
        // 验证码不通过
        if (cacheCode == null || !cacheCode.equals(code)) {
            return Result.error("验证码错误!");
        }
        // 验证码通过
        // 手机号查数据库
        User user = query().eq("phone", phone).one();
        // 不存在,创建账号
        if (user == null){
            // 创建账号
            user = createUserWithPhone(phone);

        }
        // 存在,生成jWT令牌
        Map<String,Object> claims = new HashMap<>();
        claims.put("identity","user");
        claims.put("id",user.getId());
        claims.put("username",user.getUsername());
        claims.put("phone",user.getPhone());
        //生成token
        String token = JwtUtil.createJWT(
                jwtProperties.getSecretKey(),
                jwtProperties.getTime(),
                claims);
        // 封装
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setToken(token);
        userLoginVO.setUsername(user.getUsername());
        userLoginVO.setUserId(user.getId());
        userLoginVO.setPhone(phone);
        return Result.success(userLoginVO);

    }

    @Override
    public Result<String> sendMsg(String phone) {
        // 查看redis是否有该手机和验证码
        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
        // 没有，生成验证码
        if(StringUtil.isNullOrEmpty(cacheCode)){
            // 生成验证码
            Integer code = ValidateCodeUtils.generateValidateCode(6);
            String codeValue = String.valueOf(code);
            System.out.println("验证码：=========>"+ code);
            // 发送短信
            smsUtil.sendMessage(phone, codeValue);
            // 保存redis
            stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY+phone, codeValue);
            // 设置过期时间
            stringRedisTemplate.expire(LOGIN_CODE_KEY+phone,LOGIN_CODE_TTL, TimeUnit.MINUTES);
            // 返回成功信息
            return Result.success();
        }
        //有直接返回
        return Result.error("验证码已存在！请勿重复点击");
    }


    private User createUserWithPhone(String phone) {
        // 1.创建用户
        User user = new User();
        user.setPhone(phone);
        user.setUsername("am"+ RandomUtil.randomString(10));
        user.setPassword(RandomUtil.randomString(10));
        // 2.保存用户
        save(user);
        return user;
    }
}
